package com.vpen.iot.server;

import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.Date;

public class CertificateGenerator {

    public static void main(String[] args) throws Exception {
        // 添加 BouncyCastle 提供程序
        Security.addProvider(new BouncyCastleProvider());

        // 生成 RSA 私钥
        KeyPair keyPair = generateRSAKeyPair();

        // 设置证书信息
        X500Name issuer = new X500Name("CN=JetProfile CA");
        X500Name subject = new X500Name("CN=MoYuno-from-2022-07-25");
        BigInteger serialNumber = new BigInteger(64, new SecureRandom());
        Date notBefore = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000);  // 昨天
        Date notAfter = new Date(System.currentTimeMillis() + 3650L * 24 * 60 * 60 * 1000);  // 十年后

        // 创建证书生成器
        X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
                issuer, serialNumber, notBefore, notAfter, subject, keyPair.getPublic());

        // 使用私钥对证书进行签名
        JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder("SHA256withRSA");
        signerBuilder = signerBuilder.setProvider("BC");
        ContentSigner signer = signerBuilder.build(keyPair.getPrivate());

        // 生成 X.509 证书
        X509Certificate certificate = new JcaX509CertificateConverter().getCertificate(certBuilder.build(signer));

        // 保存私钥到 PEM 文件
        savePrivateKeyToPEM(keyPair.getPrivate(), "ca.key");

        // 保存证书到 PEM 文件
        saveCertificateToPEM(certificate, "ca.crt");

        System.out.println("Certificate and private key have been generated and saved.");
    }

    // 生成 RSA 密钥对
    public static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(4096);
        return keyPairGenerator.generateKeyPair();
    }

    // 将私钥保存为 PEM 格式
    public static void savePrivateKeyToPEM(PrivateKey privateKey, String filename) throws Exception {
        try (FileOutputStream fileOut = new FileOutputStream(filename)) {
            PEMWriter pemWriter = new PEMWriter(new OutputStreamWriter(fileOut));
            pemWriter.writeObject(privateKey);
            pemWriter.flush();
        }
    }

    // 将证书保存为 PEM 格式
    public static void saveCertificateToPEM(X509Certificate certificate, String filename) throws Exception {
        try (FileOutputStream fileOut = new FileOutputStream(filename)) {
            PEMWriter pemWriter = new PEMWriter(new OutputStreamWriter(fileOut));
            pemWriter.writeObject(certificate);
            pemWriter.flush();
        }
    }
}
